﻿
#region "命名空间"

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.UI;

#endregion

namespace ZN.Common {
    /// <summary>
    /// 工具类(包含一些项目中用到的辅助方法)
    /// </summary>
    public class Utils {
        /// <summary>
        /// 数据类型转换
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="value">源数据</param>
        /// <param name="objDefault">默认值</param>
        /// <returns>结果</returns>
        public static T Cast<T>(object value, T objDefault) {
            if (value==null) return objDefault;
            T obj = default(T);
            try {
                obj = (T)Convert.ChangeType(value, typeof(T));
                if (obj == null) {
                    obj = objDefault;
                }
            } catch {
                obj = objDefault;
            }
            return obj;
        }
        /// <summary>
        /// 将对象转换为脚本字符串
        /// </summary>
        /// <param name="item">对象</param>
        /// <returns></returns>
        public static string ObjectToJavaScriptString(object item) {
            if (item is string) {
                return "'" + ((string)item).Replace("\\", "\\\\").Replace("'", "\\'").Replace("\n", "\\n").Replace("\t", "\\t").Replace("\r", "") + "'";
            } else if (item is bool) {
                return item.ToString().ToLower();
            } else if (item is Enum) {
                return ((int)item).ToString();
            } else if (item is DateTime) {
                return Utils.ConvertDateTimeToJsDate((DateTime)item);
            } else if (item is Decimal || item is Double) {
                return string.Format(CultureInfo.InvariantCulture, "{0}", item);
            } else if (item is Int16 || item is Int32 || item is Int64) {
                return item.ToString();
            } else if (item != null) {
                return ObjectToJavaScriptString(item.ToString());
            } else {
                return "";
            }
        }
        /// <summary>
        /// 转换日期为 js 格式的日期
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        public static string ConvertDateTimeToJsDate(DateTime d) {

            StringBuilder dateConstructor = new StringBuilder();
            dateConstructor.Append("new Date(");
            dateConstructor.Append(d.Year);
            dateConstructor.Append(",");
            dateConstructor.Append(d.Month - 1); // In JavaScript, 月份从0开始
            dateConstructor.Append(",");
            dateConstructor.Append(d.Day);
            dateConstructor.Append(",");
            dateConstructor.Append(d.Hour);
            dateConstructor.Append(",");
            dateConstructor.Append(d.Minute);
            dateConstructor.Append(",");
            dateConstructor.Append(d.Second);
            if (d.Millisecond > 0) {
                dateConstructor.Append(",");
                dateConstructor.Append(d.Millisecond);
            }
            dateConstructor.Append(")");
            return dateConstructor.ToString();
        }
        /// <summary>
        /// 将键值集合转为某个实体对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="values"></param>
        /// <returns></returns>
        public static T NameValueCollectionToEntity<T>(NameValueCollection values) {
            if (values==null||values.Count==0) return default(T);
            T obj=  Activator.CreateInstance<T>();
            PropertyInfo[] properties=   obj.GetType().GetProperties(BindingFlags.Instance|BindingFlags.Public);
            foreach (var item in properties) {
                if (string.IsNullOrEmpty(values[item.Name]))
                    continue;
                var value=values[item.Name];

                if (item.PropertyType==typeof(bool)) {
                    value=value=="on"?"true":"false";
                }
                item.SetValue(obj, Convert.ChangeType(value, item.PropertyType), null);
            }
            return obj;
        }

        public static T WebCast<T>(object oValue, T sDefault) {
            object oTempVal = oValue;
            if (oValue is Control) {
                oTempVal = HttpContext.Current.Request.Params[((Control)oValue).ID];
            }

            if (oTempVal == null) oTempVal = sDefault;

            if (oTempVal is string) oTempVal = HttpUtility.UrlDecode(oTempVal.ToString(), Encoding.UTF8);

            if (typeof(T) == typeof(string)) { //如果是字符串
                return Cast<T>(HttpUtility.UrlDecode(oTempVal.ToString(), Encoding.UTF8), sDefault);
            }
            if (typeof(T) == typeof(bool?)) {
                bool? b = null;
                if (oTempVal.ToString() == "1") {
                    b = true;
                } else if (oTempVal.ToString() == "0") {
                    b = false;
                }
                oTempVal = b;
            }
            return Cast<T>(oTempVal, sDefault);
        }
        public static string ConvertToJson(object obj) {
            if (obj == null) return string.Empty;
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(obj);
        }

        public static T ConvertJsonToObject<T>(string json) {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Deserialize<T>(json);
        }
        public static string SubString(string sString, int count, string suffix) {
            if (sString == null) return null;
            if (sString.Length > count)
                return sString.Substring(0, count) + suffix;
            return sString;
        }

        public static string GenerateControlHtml(Control control) {
            if (control == null) return string.Empty;
            StringWriter stringWriter = new StringWriter();
            HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
            control.RenderControl(htmlWriter);
            return stringWriter.ToString().Replace("\r\n", "").Replace("\"", "'").Replace("  ", " ");
        }

        public static int GetTotalRecords(ref IDataReader dr) {
            int total = 0;
            if (dr.Read()) {
                try {
                    total = Convert.ToInt32(dr["TotalRecords"]);
                } catch {
                    total = -1;
                }
            }
            return total;
        }

        #region "WCF相关"

        /// <summary>
        /// 复制属性
        /// </summary>
        /// <param name="sourceObj"></param>
        /// <param name="targetObj"></param>
        public static void CopyAllProperties(object sourceObj, object targetObj) {

            if (sourceObj==null) throw new ArgumentNullException("参数sourceObj不能为空");
            if (targetObj==null) throw new ArgumentNullException("参数targetObj不能为空");

            PropertyInfo[] sourceProperties=sourceObj.GetType().GetProperties(BindingFlags.Public|BindingFlags.Instance);
            PropertyInfo[] targetProperties=targetObj.GetType().GetProperties(BindingFlags.Public|BindingFlags.Instance);
            foreach (var item in targetProperties) {
                var property=(from s in sourceProperties where s.Name==item.Name select s).FirstOrDefault();
                if (property==null||!item.CanWrite||!property.CanRead) { continue; }
                item.SetValue(targetObj, property.GetValue(sourceObj, null), null);
            }
        }
        /// <summary>
        /// 批量转换 实现 IViewConverter接口的对象
        /// </summary>
        /// <typeparam name="Source">源数据对象类型</typeparam>
        /// <typeparam name="Target">目标对象类型</typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static IEnumerable<Target> CastIViewConverterObjects<Source, Target>(IEnumerable<Source> list) {
            if (list==null) throw new ArgumentNullException("参数list不能为空");
            IList<Target> targets=new List<Target>();
            foreach (var item in list) {
                var view=(IViewConverter<Source, Target>)Activator.CreateInstance<Target>();
                targets.Add(view.Convert(item));
            }
            return targets.AsEnumerable<Target>();
        }

        #endregion

    }



}
